{% extends "base.html" %} {% from "_event.html" import event_row with context %} {% from "_when.html" import when_field with context %} {% block body %} {% include "_timer.html" %} {#- THE PLAY SURFACE. Four big doors, nothing to configure. The photo door submits the moment a file is picked โ€” one tap, camera, done. Badges come from each module's dashboard_card ("due", "3 open", "ready"). -#}
{% for m, c in cards %}{% if m.nav %} {{ m.icon }}{{ m.title }}{% if c.badge %}{{ c.badge }}{% endif %} {% endif %}{% endfor %}
{#- ๐Ÿ› HYGIENE (core/hygiene.py) โ€” one tap out, one tap back in. Maintenance when the game setup has a slot open; the emergency door is there every other moment, never refused. ๐Ÿ”ด Nothing here prints the clock: on a hidden lock the window is the only number shown. -#} {% if hy %}
{% if hy.window %}

๐Ÿ› Out for {{ 'maintenance' if hy.window.kind == 'scheduled' else 'emergency hygiene' }} since {{ hy.window.start|local('%H:%M') }} ยท {% if hy.window.overrun %}past {{ hy.window.until|local('%H:%M') }} โ€” locked back up? {% else %}back by {{ hy.window.until|local('%H:%M') }} ยท clock stopped{% endif %}

{{ when_field('โฑ relocked earlier?') }}
{% else %}
{% if hy.slot %} slot open until {{ hy.slot[1]|local('%H:%M') }}{% if hy.set_by != 'you' %} ยท set by {{ hy.set_by }}{% endif %} {% else %} {% if hy.next_slot %}next maintenance {{ hy.next_slot|local('%a %H:%M') }}{% if hy.set_by != 'you' %} ยท set by {{ hy.set_by }}{% endif %}{% else %}no maintenance scheduled ยท set slots{% endif %} {% endif %} {{ when_field('โฑ went out earlier?') }}
{% endif %}
{% endif %} {#- ๐ŸŽฏ THE QUEST (M10 #60): the running chapter's goal. core/quest.py decides the verdict; this only shows it. Nothing here prints the clock. -#} {% if quest %}

๐ŸŽฏ {{ quest.title }} ยท day {{ quest.day }}{% if quest.days %} of {{ quest.days }}{% endif %}{% if quest.verdict in ('met', 'missed') %} ยท {{ 'reached' if quest.verdict == 'met' else 'not reached' }}{% endif %}

{% if quest.text %}

{{ quest.text }}

{% endif %}

{{ quest.label }} ยท the chapter

{% endif %} {#- ๐Ÿ“ค SHARE DAY N โ€” for 12 h after a photo check-in or a photo verification. One tap to /share with that photo named: the picture, the event stamp and the post text are ready on arrival. ๐Ÿ”ด The button IS the link; the flash after ๐Ÿ“ธ stays plain text (`?ok=` is untrusted, and rendering markup from it would be an injection). Writes nothing on GET. -#} {% if share_nudge %}
{{ share_nudge.label }}

your {{ share_nudge.when }} photo{% if share_nudge.event %} ยท {{ share_nudge.event }}{% endif %}: picture and post text ready

{% endif %} {#- The safeword on the play surface (R9), shown once there is something to pause โ€” a grant to somebody โ€” or while paused. No form token: a pause must never answer "page expired". -#} {% if consent_bar %}
{% if safeword_paused %}๐Ÿ›‘ Paused โ€” every grant is suspended. Resume on the Consent page โ†’ {% else %}
what they can do โ†’
{% endif %}
{% endif %}
๐Ÿ“ธ with a caption, or a photo from earlier
{{ when_field('โฑ taken earlier? set the time') }}
{% if not st.active %}

Cage up

more: dice ยท hidden timer ยท note ยท started earlier

If max > min, a random duration in that range wins over the fields above.

{{ when_field('โฑ already locked? set when it started', 'Locked since') }}

Last lock

{% if last %}

{{ last_state.elapsed|dur }}

ended {{ last.ended_at|local }} ยท base {{ last_state.base_seconds|dur }} ยท adjustments {{ last_state.adjust_seconds|sdur }}

๐Ÿ“ค share recap โฌ‡ recap card {% if last.note %}+ note{% endif %}
{% else %}

The kennel is quiet. The first lock starts the log.

{% endif %}
{% else %}

Clock โš™

{% for m in quick %}
{% endfor %} {% for m in quick %}
{% endfor %}
{% if hy and hy.window %}

๐Ÿ› The clock is stopped for hygiene โ€” lock back up to start it.

{% elif st.frozen %}
{{ when_field('โฑ thawed earlier?') }}
{% else %}
{{ when_field('โฑ froze earlier?') }}
{% endif %}
fine adjust ยท with a reason ยท for earlier
{{ when_field() }}

Session

{{ when_field() }}
{% if undo_ev %} {#- The label MUST name its target. A wheel spin with effect=freeze emits the spin and then the freeze at the same ts, and the (ts, id) sort makes the FREEZE the newest โ€” so a bare "Undo" pressed after a spin would eat the freeze and leave the spin standing. Naming it makes that visible instead of surprising. -#}
{% if undo_why %}

{{ undo_why }}

{% endif %} {% endif %}
{% if st.can_unlock %}
{% else %} {# ๐Ÿ”ด A FOURTH LEAK, and the most direct of them: this confirm() printed `remaining` VERBATIM on a hidden lock โ€” not an operand of end_at, the countdown itself, in a dialog you cannot avoid reading because you must click it. Gated like the clock. #}
{% endif %}

๐Ÿ“ค share where this lock stands

{% endif %}
{% include "_acts.html" %}
{% for m, c in cards %}

{{ m.icon }} {{ m.title }} โš™

{% include c.template %}
{% endfor %}

Recent timeline โ†’

{% if recent %} {% else %}

The log is empty.

{% endif %}
{% endblock %}